package com.xhlj.utils;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson2.JSON;
import io.jsonwebtoken.*;
import jakarta.annotation.Resource;
import jakarta.validation.Payload;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Data
@Component
@ConfigurationProperties(prefix = "jwt.token")
public class JwtHelper {

    private long tokenExpiration; //有效时间,单位毫秒 1000毫秒 == 1秒
    private String tokenSignKey;  //当前程序签名秘钥
    @Resource
    StringRedisTemplate stringRedisTemplate;


    public String createToken(PayLoad payload) {
        System.out.println("tokenExpiration = " + tokenExpiration + "分钟");
        System.out.println("tokenSignKey = " + tokenSignKey);
        /*创建的时候把 : -> @ */
        String data = JSON.toJSONString(payload).replaceAll(":", "@");
        String token = Jwts.builder()
                .setSubject("YYGH-USER")
                .setExpiration(new Date(System.currentTimeMillis() + tokenExpiration * 60 * 1000)) //单位分钟
                .claim("payload", data)
                .signWith(SignatureAlgorithm.HS512, tokenSignKey)
                .compressWith(CompressionCodecs.GZIP)
                .compact();
//        存入redis,方便刷新Token
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        ops.set(RedisKey.Login_token_prefix + data, token, tokenExpiration, TimeUnit.MINUTES);
        return token;
    }

    //从token字符串获取userid
    public PayLoad getPayLoad(String token) {
        if (StringUtils.isEmpty(token)) return null;

        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(tokenSignKey).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        String str = (String) claims.get("payload");
        String data = str.replaceAll("@", ":");
        PayLoad res = JSON.parseObject(data, PayLoad.class);
        return res;
    }


    //判断token是否有效
    public boolean isExpiration(String token) {
        try {
            boolean isExpire = Jwts.parser()
                    .setSigningKey(tokenSignKey)
                    .parseClaimsJws(token)
                    .getBody().getExpiration().before(new Date());

            //没有过期，有效，返回false
            return isExpire;
        } catch (Exception e) {
            //过期出现异常，返回true
            return true;
        }
    }

    //    refresh Token
    public String refreshToken(String token) {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        PayLoad payLoad = getPayLoad(token);
        String key = JSON.toJSONString(payLoad).replaceAll(":", "@");
        if (isExpiration(token)) {
            String ntoken = createToken(payLoad);
            ops.set(RedisKey.Login_token_prefix + key, ntoken, tokenExpiration, TimeUnit.MINUTES);
            return ntoken;
        } else {

            ops.set(RedisKey.Login_token_prefix + key, token, tokenExpiration, TimeUnit.MINUTES);
            return token;
        }
    }

    public void removeToken(PayLoad payload) {
        String data = JSON.toJSONString(payload).replaceAll(":", "@");
        stringRedisTemplate.delete(RedisKey.Login_token_prefix + data);

    }


}
